#ifndef __ATL_FDC_H__
#define __ATL_FDC_H__
#include <cstdint.h>
#define FDC_MAX_IO_TRIES 500
#define FDC_CMD_CFG_SKIP 0x20
#define FDC_CMD_CFG_DENS 0x40
#define FDC_CMD_CFG_MTRK 0x80
#define FDD_SECTORS_PER_TRACK 80

typedef struct FloppyDOR {
	unsigned drive_select :2;
	unsigned reset		  :1;
	unsigned dma		  :1;
	unsigned motor0		  :1;
	unsigned motor1		  :1;
	unsigned motor2		  :1;
	unsigned motor3		  :1;
} FloppyDORT;

typedef struct FloppyMSR {
	unsigned act0		  :1;
	unsigned act1		  :1;
	unsigned act2		  :1;
	unsigned act3		  :1;
	unsigned busy		  :1;
	unsigned ndma		  :1;
	unsigned dio		  :1;
	unsigned mrq		  :1;
} FloppyMSRT;

typedef struct FloppyST0 {
	unsigned drive_select :2;//0
	unsigned active_head  :1;//2
	unsigned not_ready    :1;//3
	unsigned unit_check   :1;//4
	unsigned seek_end	  :1;//5
	unsigned interrupt_id :2;//6
} FloppyST0T;

typedef struct FloppyST1 {
	unsigned no_id		  :1;
	unsigned read_only	  :1;
	unsigned no_data	  :1;
	unsigned timeout	  :1;
	unsigned data_err	  :1;
	unsigned unused		  :1;
	unsigned end_of_cyl	  :1;
} FloppyST1T;

typedef struct FloppyST2 {
	unsigned no_dam		  :1;
	unsigned bad_cyl	  :1;
	unsigned seek_err	  :1;
	unsigned seek_equ	  :1;
	unsigned wrong_cyl	  :1;
	unsigned crc_error	  :1;
	unsigned deleted_dam  :1;
	unsigned unused		  :1;
} FloppyST2T;

typedef struct FloppyST3 {
	unsigned drive_select  :2;
	unsigned active_head   :1;
	unsigned dbl_sided	   :1;
	unsigned track0_active :1;
	unsigned ready		   :1;
	unsigned read_only	   :1;
	unsigned error		   :1;
} FloppyST3T;

/* Floppy enumerations are copied from http://wiki.osdev.org/Floppy_Disk_Controller */

enum FloppyGAP3Length {
 
	STD    = 42,
	F_5_14 = 32,
	F_3_5  = 27
};

enum FloppySectorLength {
 
	F_128	=	0,
	F_256	=	1,
	F_512	=	2,
	F_1024	=	4
};

enum FloppyDorMasks { 
	DRIVE0			=	0,	//00000000	= here for completeness sake
	DRIVE1			=	1,	//00000001
	DRIVE2			=	2,	//00000010
	DRIVE3			=	3,	//00000011
	RESET			=	4,	//00000100
	DMA				=	8,	//00001000
	DRIVE0_MOTOR	=	16,	//00010000
	DRIVE1_MOTOR	=	32,	//00100000
	DRIVE2_MOTOR	=	64,	//01000000
	DRIVE3_MOTOR	=	128	//10000000
};

enum FloppyRegisters
{
   STATUS_REGISTER_A                = 0x3F0, // read-only
   STATUS_REGISTER_B                = 0x3F1, // read-only
   DIGITAL_OUTPUT_REGISTER          = 0x3F2,
   TAPE_DRIVE_REGISTER              = 0x3F3,
   MAIN_STATUS_REGISTER             = 0x3F4, // read-only
   DATARATE_SELECT_REGISTER         = 0x3F4, // write-only
   DATA_FIFO                        = 0x3F5,
   DIGITAL_INPUT_REGISTER           = 0x3F7, // read-only
   CONFIGURATION_CONTROL_REGISTER   = 0x3F7  // write-only
};

enum FloppyCommands
{
   READ_TRACK =                 2,	// generates IRQ6
   SPECIFY =                    3,      // * set drive parameters
   SENSE_DRIVE_STATUS =         4,
   WRITE_DATA =                 5,      // * write to the disk
   READ_DATA =                  6,      // * read from the disk
   RECALIBRATE =                7,      // * seek to cylinder 0
   SENSE_INTERRUPT =            8,      // * ack IRQ6, get status of last command
   WRITE_DELETED_DATA =         9,
   READ_ID =                    10,	// generates IRQ6
   READ_DELETED_DATA =          12,
   FORMAT_TRACK =               13,     // *
   SEEK =                       15,     // * seek both heads to cylinder X
   VERSION =                    16,	// * used during initialization, once
   SCAN_EQUAL =                 17,
   PERPENDICULAR_MODE =         18,	// * used during initialization, once, maybe
   CONFIGURE =                  19,     // * set controller parameters
   LOCK =                       20,     // * protect controller params from a reset
   VERIFY =                     22,
   SCAN_LOW_OR_EQUAL =          25,
   SCAN_HIGH_OR_EQUAL =         29
};

#endif 